package me.keiwu.task.service.impl;

import me.keiwu.pub.data.LockKeyEnum;
import me.keiwu.pub.util.CacheUtil;
import me.keiwu.pub.util.DateUtil;
import me.keiwu.pub.util.redis.RedisLock;
import me.keiwu.task.rpc.LogDonateRpc;
import me.keiwu.task.service.DonateService;
import me.keiwu.task.util.ExceptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * Created by kei on 18/12/2017.
 */
@Service
public class DonateServiceImpl implements DonateService {

    private static final Logger logger = LoggerFactory.getLogger(DonateServiceImpl.class);

    @Autowired
    private LogDonateRpc logDonateRpc;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private ExceptionUtil exceptionUtil;


    @Override
    public boolean donateStep(Long userId, Integer donateStep) {
        if (donateStep <= 0) return false;

        String lockKey = LockKeyEnum.UPDATE_TOTAL_DONATE_STEP.getLockKey(userId);
        String requestId = UUID.randomUUID().toString();

        try {
            if (!redisLock.tryLock(lockKey, requestId)) return false;
            int step = cacheUtil.getUserDonateSteps(userId);
            if (step <= 0) {
                // 第一次捐，记录人数
                cacheUtil.incrTotalDonateUsers();
                cacheUtil.setUserDonateSteps(userId, donateStep);
            } else {
                int userDonateStep = donateStep;
                donateStep = donateStep - step;
                if (donateStep <= 0) {
                    logger.warn("not donate! donateStep={}, userDonateStep={}, step={}", donateStep, userDonateStep, step);
                    return false;
                }
                cacheUtil.setUserDonateSteps(userId, userDonateStep);
            }
            // 增加总步数
            cacheUtil.incrTotalDonateSteps(donateStep);

            // 写日志
            logDonateRpc.logDonateStep(userId, donateStep, DateUtil.getUnixTime());
            return true;
        } catch (Exception e) {
            logger.error("donateStep exception: ", e);
            exceptionUtil.logError(this.getClass(), "donateStep", "donateStep exception");
            return false;
        } finally {
            redisLock.release(lockKey, requestId);
        }
    }


}
